import React from 'react';
import { Button, Popover } from 'antd';
import Selector from 'components/selector';
import Chooser from 'components/chooser';
import Searcher from 'components/searcher'
import CustomTable from 'components/custom-table'
import httpFetch from 'share/httpFetch'
import {getSearchForm} from "share/common";

class DataSourceTable extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      dataSource: [],
      pagination: {
        total: 0,
        showSizeChanger: true,
        pageSizeOptions: ['10', '50', '100'],
      },
      page: 0,
      size: 10,
      sorter: {},
      searchParams: {}
    }
  }

  componentDidMount() {
    const { searchParams } = this.state;
    this.getList(searchParams);
  }

  getList = (params) => {
    let { pagination, page } = this.state;
    this.setState({
      loading: true,
      searchParams: params
    }, () => this.getListFetch().then(res => {
      pagination.total = Number(res.headers['x-total-count']);
      pagination.current = page + 1;
      this.setState({
        loading: false,
        dataSource: res.data,
        pagination
      })
    }));
  };

  getListFetch = (extraParams = {}) => {
    let { page, searchParams, sorter } = this.state;
    const { source } = this.props;
    const { url, method } = source;
    let size = extraParams.size || this.state.size;
    let baseParams = method === 'get' ? { page, size } : {};
    if(sorter.field) {
      baseParams.sorts = {
        property: sorter.field,
        direction: sorter.order === 'descend' ? 'DESC' : 'ASC'
      };
    }
    let postPageString = `?page=${page}&size=${size}`;
    return httpFetch[method](
      `${url}${method === 'post' ? postPageString : ''}`,
      Object.assign({}, searchParams, baseParams, source.params, extraParams)
    )
  };

  onChangeTable = (pagination, filters, sorter) => {
    this.setState({ page: pagination.current - 1, size: pagination.pageSize, sorter }, this.getList)
  };

  getTableOption = (tableOption, source) => {
    const { loading, dataSource, pagination } = this.state;
    let tableOptionFromState = { loading, dataSource, pagination };
    let target = {};
    target.columns = this.getAllColumns(tableOption, source);
    target.rowKey = source.mainKey;
    target.bordered = true;
    target.size = 'middle';
    if(tableOption.rowKey)
      target.rowKey = tableOption.rowKey;
    target.onChange = this.onChangeTable;
    return Object.assign(
      {},
      tableOption,
      tableOptionFromState,
      target);
  };

  getAllColumns = (tableOption, source) => {
    let columns = JSON.parse(JSON.stringify(source.keys));
    columns.forEach(column => {
      column.render = data => (
        <Popover content={data}>
          {data}
        </Popover>)
    });
    if(tableOption.columns) {
      tableOption.columns.map(column => {
        let hasThisColumn = false;
        columns.forEach(c => {
          if(c.dataIndex === column.dataIndex) {
            hasThisColumn = true;
            Object.keys(column).map(key => {
              c[key] = column[key];
            })
          }
        });
        if(!hasThisColumn) {
          columns.push(column);
        }
      })
    }
    return columns;
  };

  render() {
    const { source, tableOption = {}, id, template, pageOption } = this.props;
    return (
      <div>
        <div className="table-header">
          {template && pageOption && pageOption.buttons && (
            <div className="table-header-buttons">
              {pageOption.buttons.map(button => (
                <Button type={button.type} onClick={button.onClick}>{button.text}</Button>
              ))}
            </div>
          )}
        </div>
        <CustomTable
          allColumns={this.getAllColumns(tableOption, source)}
          localKey={id}
          source={source}
          onChange={(params) => this.getList(params)}
          showOperation
          tableOption={this.getTableOption(tableOption, source)}
        />
      </div>
    )
  }
}

class DataSource extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: props.selectOption && props.selectOption.single ? null : []
    }
  }

  componentDidMount() {
  }

  componentWillReceiveProps(nextProps) {
    if(nextProps.value) {
      this.setState({ value: nextProps.value });
    }
  }

  onChange = changedValue => {
    this.setState({ value: changedValue });
    const { onChange } = this.props;
    if (onChange) {
      onChange(changedValue);
    }
  };

  render() {
    const { source, type, selectOption = {} } = this.props;
    const { value } = this.state;
    switch(type) {
      case 'table':
        return <DataSourceTable {...this.props}/>;
      case 'page':
        return <DataSourceTable {...this.props} template/>;
      case 'select':
        if(source.paging) {
          let chooserItem = {
            title: selectOption.title,
            url: source.url,
            searchForm: getSearchForm(source.searchParams),
            columns: source.keys,
            key: source.mainKey
          };
          return <Chooser
            selectorItem={chooserItem}
            value={value}
            onChange={this.onChange}
            valueKey={source.mainKey}
            single={selectOption.single}
            labelKey={selectOption.labelKey}
          />
        } else {
          if(selectOption.single) {
            let selectorItem = {
              url: source.url,
              label: selectOption.labelKey,
              key: source.mainKey,
              showSearch: true,
              offlineSearchMode: true
            };
            if(source.searchParams.length === 1 && source.searchParams[0].type === 'String') {
              selectorItem.offlineSearchMode = false;
              selectorItem.searchKey = source.searchParams[0].name;
            }
            return <Selector
              selectorItem={selectorItem}
              value={value}
              entity={source.entity}
              onChange={this.onChange}
            />
          } else {
            let searcherItem = {
              title: selectOption.title,
              url: source.url,
              key: source.mainKey
            };
            return <Searcher
              searcherItem={searcherItem}
              value={value}
              labelKey={selectOption.labelKey}
              onChange={this.onChange}
            />
          }
        }
    }
  }
}

DataSource.propTypes = {
  source: React.PropTypes.object
};

DataSource.defaultProps = {

};

export default DataSource;
